/**
 * ConnectionCatalog.java
 * @author Daniel Liu
 * 2006-12-22 ����12:18:01
 */
package org.lex.ftp.ui.prefs;

import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.nio.charset.Charset;
import java.util.Locale;
import javax.swing.*;
import javax.swing.border.TitledBorder;

import org.lex.app.prefs.ResourceMap;
import org.lex.awt.ComponentUtilities;
import org.lex.ftp.FTP;
import org.lex.ftp.util.prefs.Keys;
import org.lex.swing.Swings;
import org.lex.swing.prefs.CategoryAdapter;
import org.lex.swing.widgets.JCharsetChooser;


public class ConnectionCategory extends CategoryAdapter {
	private static final String[] COMMON_ENCODINGS = { "GB2312", "GBK", "GB18030", "BIG5", "US-ASCII", "UTF-8", "UTF-16", "UTF-16LE", "UTF-16BE" };
	private JPanel connectionPane = null;
	private JLabel timeoutLabel = null;
	private JTextField timeoutTextField = null;
	private JCheckBox enableAutoReconnectCheckBox = null;
	private JLabel retryDelayLabel = null;
	private JTextField retryDelayTextField = null;
	private JLabel retryCountLabel = null;
	private JTextField retryCountTextField = null;
	// ============================================
	private JPanel gluePane = null;
	private JPanel charsetPane = null;
	private JRadioButton defaultCharsetRadioButton = null;
	private JRadioButton specifyCharsetRadioButton = null;
	private JComboBox charsetComboBox = null;
	private JButton moreCharsetButton = null;

	public ConnectionCategory() {
		super();
		this.initialize();
	}

	public Component getComponent() {
		return this;
	}

	public String getTitle() {
		return "Net.Connection";
	}

	public void loadConfiguration() {
		ResourceMap rm = FTP.getContext().getResourceMap();
		String timeout = rm.getString(Keys.CONNECT_TIMEOUT);
		this.getTimeoutTextField().setText(timeout);
		String delay = rm.getString(Keys.CONNECT_RETRY_DELAY);
		this.getRetryDelayTextField().setText(delay);
		String count = rm.getString(Keys.CONNECT_RETRY_COUNT);
		this.getRetryCountTextField().setText(count);
		boolean autoRetry = rm.getBoolean(Keys.CONNECT_RETRY_ENABLED);
		this.getEnableAutoReconnectCheckBox().setSelected(autoRetry);
		// charset
		String charset = rm.getString(Keys.SERVER_CHARSET, "");
		if (true == charset.equals(Charset.defaultCharset().name()))
			this.getDefaultCharsetRadioButton().setSelected(true);
		else {
			this.getSpecifyCharsetRadioButton().setSelected(true);
			if (false == this.contains(charset))
				this.getCharsetComboBox().addItem(charset);
			this.getCharsetComboBox().setSelectedItem(charset);
		}
	}

	public void saveConfiguration() {
		ResourceMap rm = FTP.getContext().getResourceMap();
		String timeout = this.getTimeoutTextField().getText().trim();
		String delay = this.getRetryDelayTextField().getText().trim();
		String count = this.getRetryCountTextField().getText().trim();
		boolean enabled = this.getEnableAutoReconnectCheckBox().isSelected();
		rm.putProperty(Keys.CONNECT_TIMEOUT, timeout);
		rm.putProperty(Keys.CONNECT_RETRY_DELAY, delay);
		rm.putProperty(Keys.CONNECT_RETRY_COUNT, count);
		rm.putProperty(Keys.CONNECT_RETRY_ENABLED, enabled);
		// charset
		String charset = null;
		if (true == this.getDefaultCharsetRadioButton().isSelected())
			charset = Charset.defaultCharset().name();
		else
			charset = String.valueOf(getCharsetComboBox().getSelectedItem());
		rm.putProperty(Keys.SERVER_CHARSET, charset);
	}

	// =======================
	private void initialize() {
		GridBagConstraints gridBagConstraints9 = new GridBagConstraints();
		gridBagConstraints9.gridx = 0;
		gridBagConstraints9.fill = GridBagConstraints.HORIZONTAL;
		gridBagConstraints9.weightx = 1.0;
		gridBagConstraints9.gridy = 1;
		GridBagConstraints gridBagConstraints8 = new GridBagConstraints();
		gridBagConstraints8.gridx = 0;
		gridBagConstraints8.fill = GridBagConstraints.HORIZONTAL;
		gridBagConstraints8.weightx = 1.0;
		gridBagConstraints8.anchor = GridBagConstraints.CENTER;
		gridBagConstraints8.gridy = 0;
		GridBagConstraints gridBagConstraints7 = new GridBagConstraints();
		gridBagConstraints7.gridheight = 0;
		gridBagConstraints7.gridx = 0;
		gridBagConstraints7.gridy = 2;
		gridBagConstraints7.fill = GridBagConstraints.BOTH;
		gridBagConstraints7.weightx = 1.0;
		gridBagConstraints7.weighty = 1.0;
		gridBagConstraints7.gridwidth = 0;
		this.setSize(375, 260);
		this.setLayout(new GridBagLayout());
		this.add(getConnectionPane(), gridBagConstraints8);
		this.add(getCharsetPane(), gridBagConstraints9);
		this.add(getGluePane(), gridBagConstraints7);
	}

	private JPanel getConnectionPane() {
		if (null == this.connectionPane) {
			GridBagConstraints gridBagConstraints6 = new GridBagConstraints();
			gridBagConstraints6.fill = GridBagConstraints.NONE;
			gridBagConstraints6.gridy = 3;
			gridBagConstraints6.weightx = 0.0;
			gridBagConstraints6.insets = new Insets(0, 6, 5, 5);
			gridBagConstraints6.ipadx = 100;
			gridBagConstraints6.anchor = GridBagConstraints.WEST;
			gridBagConstraints6.gridx = 1;
			GridBagConstraints gridBagConstraints5 = new GridBagConstraints();
			gridBagConstraints5.gridx = 0;
			gridBagConstraints5.anchor = GridBagConstraints.WEST;
			gridBagConstraints5.insets = new Insets(0, 24, 5, 0);
			gridBagConstraints5.fill = GridBagConstraints.NONE;
			gridBagConstraints5.gridy = 3;
			retryCountLabel = new JLabel();
			retryCountLabel.setText("Reconnect Count");
			GridBagConstraints gridBagConstraints4 = new GridBagConstraints();
			gridBagConstraints4.fill = GridBagConstraints.NONE;
			gridBagConstraints4.gridy = 2;
			gridBagConstraints4.weightx = 0.0;
			gridBagConstraints4.insets = new Insets(0, 6, 5, 5);
			gridBagConstraints4.ipadx = 100;
			gridBagConstraints4.anchor = GridBagConstraints.WEST;
			gridBagConstraints4.gridx = 1;
			GridBagConstraints gridBagConstraints3 = new GridBagConstraints();
			gridBagConstraints3.gridx = 0;
			gridBagConstraints3.anchor = GridBagConstraints.WEST;
			gridBagConstraints3.insets = new Insets(0, 24, 5, 0);
			gridBagConstraints3.fill = GridBagConstraints.NONE;
			gridBagConstraints3.gridy = 2;
			retryDelayLabel = new JLabel();
			retryDelayLabel.setText("Reconnect Delay");
			GridBagConstraints gridBagConstraints2 = new GridBagConstraints();
			gridBagConstraints2.gridx = 0;
			gridBagConstraints2.anchor = GridBagConstraints.WEST;
			gridBagConstraints2.insets = new Insets(0, 2, 5, 0);
			gridBagConstraints2.gridwidth = 2;
			gridBagConstraints2.fill = GridBagConstraints.NONE;
			gridBagConstraints2.weightx = 1.0;
			gridBagConstraints2.gridy = 1;
			GridBagConstraints gridBagConstraints1 = new GridBagConstraints();
			gridBagConstraints1.fill = GridBagConstraints.NONE;
			gridBagConstraints1.gridy = 0;
			gridBagConstraints1.weightx = 0.0;
			gridBagConstraints1.insets = new Insets(0, 6, 5, 5);
			gridBagConstraints1.ipadx = 100;
			gridBagConstraints1.anchor = GridBagConstraints.WEST;
			gridBagConstraints1.gridx = 1;
			GridBagConstraints gridBagConstraints = new GridBagConstraints();
			gridBagConstraints.gridx = 0;
			gridBagConstraints.anchor = GridBagConstraints.WEST;
			gridBagConstraints.insets = new Insets(0, 5, 5, 0);
			gridBagConstraints.fill = GridBagConstraints.HORIZONTAL;
			gridBagConstraints.weightx = 0.0;
			gridBagConstraints.gridy = 0;
			timeoutLabel = new JLabel();
			timeoutLabel.setText("Connect Timeout");
			connectionPane = new JPanel();
			connectionPane.setLayout(new GridBagLayout());
			connectionPane.setBorder(BorderFactory.createTitledBorder(null, "Connection", TitledBorder.DEFAULT_JUSTIFICATION,
					TitledBorder.DEFAULT_POSITION, new Font("Dialog", Font.BOLD, 12), new Color(51, 51, 51)));
			connectionPane.add(timeoutLabel, gridBagConstraints);
			connectionPane.add(getTimeoutTextField(), gridBagConstraints1);
			connectionPane.add(getEnableAutoReconnectCheckBox(), gridBagConstraints2);
			connectionPane.add(retryDelayLabel, gridBagConstraints3);
			connectionPane.add(getRetryDelayTextField(), gridBagConstraints4);
			connectionPane.add(retryCountLabel, gridBagConstraints5);
			connectionPane.add(getRetryCountTextField(), gridBagConstraints6);
		}
		return this.connectionPane;
	}

	private JTextField getTimeoutTextField() {
		if (timeoutTextField == null) {
			timeoutTextField = new JTextField();
		}
		return timeoutTextField;
	}

	private JCheckBox getEnableAutoReconnectCheckBox() {
		if (enableAutoReconnectCheckBox == null) {
			enableAutoReconnectCheckBox = new JCheckBox();
			enableAutoReconnectCheckBox.setText("Enable Auto-Reconnect");
			enableAutoReconnectCheckBox.addActionListener(new ActionListener() {
				public void actionPerformed(ActionEvent e) {
					boolean selected = enableAutoReconnectCheckBox.isSelected();
					ComponentUtilities.setEnabled(selected, getRetryDelayTextField(), retryDelayLabel, retryCountLabel, getRetryCountTextField());
				}
			});
		}
		return enableAutoReconnectCheckBox;
	}

	private JTextField getRetryDelayTextField() {
		if (retryDelayTextField == null) {
			retryDelayTextField = new JTextField();
		}
		return retryDelayTextField;
	}

	private JTextField getRetryCountTextField() {
		if (retryCountTextField == null) {
			retryCountTextField = new JTextField();
		}
		return retryCountTextField;
	}

	private JPanel getGluePane() {
		if (gluePane == null) {
			gluePane = new JPanel();
			gluePane.setLayout(new GridBagLayout());
		}
		return gluePane;
	}

	private JPanel getCharsetPane() {
		if (charsetPane == null) {
			GridBagConstraints gridBagConstraints13 = new GridBagConstraints();
			gridBagConstraints13.gridx = 2;
			gridBagConstraints13.anchor = GridBagConstraints.WEST;
			gridBagConstraints13.insets = new Insets(0, 5, 6, 6);
			gridBagConstraints13.gridy = 1;
			GridBagConstraints gridBagConstraints12 = new GridBagConstraints();
			gridBagConstraints12.fill = GridBagConstraints.NONE;
			gridBagConstraints12.gridy = 1;
			gridBagConstraints12.weightx = 0.0;
			gridBagConstraints12.ipadx = 25;
			gridBagConstraints12.anchor = GridBagConstraints.WEST;
			gridBagConstraints12.insets = new Insets(0, 5, 6, 0);
			gridBagConstraints12.gridx = 1;
			GridBagConstraints gridBagConstraints11 = new GridBagConstraints();
			gridBagConstraints11.gridx = 0;
			gridBagConstraints11.anchor = GridBagConstraints.WEST;
			gridBagConstraints11.insets = new Insets(0, 0, 6, 0);
			gridBagConstraints11.gridy = 1;
			GridBagConstraints gridBagConstraints10 = new GridBagConstraints();
			gridBagConstraints10.gridx = 0;
			gridBagConstraints10.fill = GridBagConstraints.HORIZONTAL;
			gridBagConstraints10.anchor = GridBagConstraints.WEST;
			gridBagConstraints10.weightx = 1.0;
			gridBagConstraints10.gridwidth = 3;
			gridBagConstraints10.gridy = 0;
			charsetPane = new JPanel();
			charsetPane.setLayout(new GridBagLayout());
			charsetPane.setBorder(BorderFactory.createTitledBorder(null, "Charset", TitledBorder.DEFAULT_JUSTIFICATION,
					TitledBorder.DEFAULT_POSITION, new Font("Dialog", Font.BOLD, 12), new Color(51, 51, 51)));
			charsetPane.add(getDefaultCharsetRadioButton(), gridBagConstraints10);
			charsetPane.add(getSpecifyCharsetRadioButton(), gridBagConstraints11);
			charsetPane.add(getCharsetComboBox(), gridBagConstraints12);
			charsetPane.add(getMoreCharsetButton(), gridBagConstraints13);
			Swings.createButtonGroup(this.getDefaultCharsetRadioButton(), this.getSpecifyCharsetRadioButton());
		}
		return charsetPane;
	}

	private JRadioButton getDefaultCharsetRadioButton() {
		if (defaultCharsetRadioButton == null) {
			defaultCharsetRadioButton = new JRadioButton();
			String text = "System Default ( " + Charset.defaultCharset().displayName(Locale.getDefault()) + " )";
			defaultCharsetRadioButton.setText(text);
			defaultCharsetRadioButton.setSelected(true);
			defaultCharsetRadioButton.addItemListener(new ItemListener() {
				public void itemStateChanged(ItemEvent e) {
					boolean selected = defaultCharsetRadioButton.isSelected();
					ComponentUtilities.setEnabled(!selected, getCharsetComboBox(), getMoreCharsetButton());
				}
			});
		}
		return defaultCharsetRadioButton;
	}

	private JRadioButton getSpecifyCharsetRadioButton() {
		if (specifyCharsetRadioButton == null) {
			specifyCharsetRadioButton = new JRadioButton();
			specifyCharsetRadioButton.setText("Specify");
			specifyCharsetRadioButton.setSelected(true);
		}
		return specifyCharsetRadioButton;
	}

	private JComboBox getCharsetComboBox() {
		if (charsetComboBox == null) {
			charsetComboBox = new JComboBox(COMMON_ENCODINGS);
			charsetComboBox.setEnabled(false);
			charsetComboBox.setEditable(true);
		}
		return charsetComboBox;
	}

	private JButton getMoreCharsetButton() {
		if (moreCharsetButton == null) {
			moreCharsetButton = new JButton();
			moreCharsetButton.setText("More");
			moreCharsetButton.setEnabled(false);
			moreCharsetButton.addActionListener(new ActionListener() {
				public void actionPerformed(ActionEvent e) {
					Charset charset = JCharsetChooser.showSingleSelection(ComponentUtilities.getAncestor(Window.class, ConnectionCategory.this));
					if (null != charset) {
						String name = charset.name();
						if (false == contains(name))
							charsetComboBox.addItem(name);
						charsetComboBox.setSelectedItem(name);
						System.out.println(charset);
					}
				}
			});
		}
		return moreCharsetButton;
	}

	private boolean contains(String item) {
		int count = charsetComboBox.getItemCount();
		for (int i = 0; i < count; i++)
			if (true == charsetComboBox.getItemAt(i).equals(item))
				return true;
		return false;
	}
}
